//
// Created by kyle on 25-7-16.
//

#include "TextRenderer.h"

//初始化屏幕
void TextRenderer::init_frame() {
    if (fb_->init()) {
        std::cout << "使用帧缓冲..." << "\n";
        fb_->clear_back_buffer(0, 0, 0);
        fb_->update_screen();
        ensure_initialized();
    } else {
        //
        std::cout << "屏幕初始化错误" << "\n";
    }
}

/**
 * 最重要的渲染函数
 * @param text
 * @param x
 * @param y
 * @param color
 * @param font_size
 * @param contain
 * @param orientation
 */
void TextRenderer::render_text(const std::string &text, int x, int y, uint16_t color,
                               int font_size, bool contain, Orientation orientation) {
    if (text.empty()) return;
    ensure_initialized();
    fb_->clear_back_buffer(0, 0, 0);
    if (contain) {
        // 使用Util类计算最佳字体大小
        TextObject result = Util::calculateBestFontSize(fb_->width, fb_->height, font_renderer_->get_font_radio(),
                                                        text);

        std::cout << "合适的字体尺寸信息:" << std::endl;
        std::cout << "字符宽度: " << result.width << " 像素" << std::endl;
        std::cout << "总行高: " << result.height << " 像素" << std::endl;
        std::unique_ptr<FontMetricsTool> fmt = std::make_unique<FontMetricsTool>(font_renderer_->get_face());
        font_size = fmt->findMaxFontSize('中', result.width, result.height);
        std::cout << "字体大小: " << font_size << std::endl;
        render_horizontal(text, 0, fb_->height - result.height, color, font_size);
    } else {
        int max_size = calculate_max_font_size(text, x, y, orientation);
        font_size = std::min(font_size, max_size);
        if (orientation == Orientation::Horizontal) {
            render_horizontal(text, x, y, color, font_size);
        } else {
            render_vertical(text, x, y, color, font_size);
        }
    }
}

void TextRenderer::display() const {
    if (fb_) {
        fb_->update_screen();
    }
}

void TextRenderer::ensure_initialized() {
    if (!initialized_ && font_renderer_) {
        bool init = font_renderer_->init();
        if (!init) {
            throw std::runtime_error("Font initialization failed");
        }
        initialized_ = true;
    }
}

int TextRenderer::calculate_max_font_size(const std::string &text, int start_x, int start_y, Orientation orientation) {
    if (!fb_ || !font_renderer_) return 1;

    int max_size = std::min(fb_->width, fb_->height);
    for (int size = max_size; size >= 1; size--) {
        if (can_fit_text(text, start_x, start_y, size, orientation)) {
            return size;
        }
    }
    return 1;
}

bool TextRenderer::can_fit_text(const std::string &text, int start_x, int start_y, int font_size,
                                Orientation orientation) {
    if (!fb_ || !font_renderer_) return false;

    int x = start_x;
    int y = start_y;

    for (size_t i = 0; i < text.size();) {
        uint32_t char_code = 0;
        size_t char_len = decode_utf8(text, i, char_code);

        bool is_chinese = font_renderer_->is_chinese_char(char_code);
        auto metrics = font_renderer_->get_glyph_metrics(char_code, font_size, is_chinese);

        if (orientation == Orientation::Horizontal) {
            if (x + metrics.advance > fb_->width) {
                x = start_x;
                y += font_size;
            }

            if (y + metrics.height > fb_->height) {
                return false;
            }

            x += metrics.advance;
        } else {
            if (y + metrics.height > fb_->height) {
                y = start_y;
                x += font_size;
            }

            if (x + metrics.width > fb_->width) {
                return false;
            }

            y += metrics.height;
        }

        i += char_len;
    }

    return true;
}

void TextRenderer::render_horizontal(const std::string &text, int start_x, int start_y,
                                     uint16_t color, int font_size) {
    ensure_initialized();
    if (!fb_ || !font_renderer_) return;

    int x = start_x;
    int y = start_y;
    bool truncated = false;

    for (size_t i = 0; i < text.size() && !truncated;) {
        uint32_t char_code = 0;
        size_t char_len = decode_utf8(text, i, char_code);

        bool is_chinese = font_renderer_->is_chinese_char(char_code);
        GlyphMetrics metrics = font_renderer_->get_glyph_metrics(char_code, font_size, true);

        // 检查是否需要换行
        if (x + metrics.advance > fb_->width) {
            x = start_x;
            y -= font_size;

            // 检查是否超出屏幕底部
            if (y < 0) {
                // 在上一行末尾添加省略号
                if (x > start_x) {
                    render_ellipsis(x, y - font_size, color, font_size);
                }
                return;
            }
        }

        // 检查是否超出屏幕右侧
        if (x + metrics.width > fb_->width) {
            render_ellipsis(x, y, color, font_size);
            return;
        }

        // 渲染字符
        font_renderer_->render_char(fb_, char_code, x, y, color, font_size, is_chinese);
        x += metrics.advance;
        i += char_len;
    }
}

void TextRenderer::render_vertical(const std::string &text, int start_x, int start_y,
                                   uint16_t color, int font_size) {
    ensure_initialized();
    if (!fb_ || !font_renderer_) return;

    int x = start_x;
    int y = start_y;
    bool truncated = false;

    for (size_t i = 0; i < text.size() && !truncated;) {
        uint32_t char_code = 0;
        size_t char_len = decode_utf8(text, i, char_code);

        bool is_chinese = font_renderer_->is_chinese_char(char_code);
        auto metrics = font_renderer_->get_glyph_metrics(char_code, font_size, is_chinese);

        // 检查是否需要换列
        if (y + metrics.height > fb_->height) {
            y = start_y;
            x += font_size;

            // 检查是否超出屏幕右侧
            if (x + metrics.width > fb_->width) {
                // 在上一列底部添加省略号
                if (y > start_y) {
                    render_ellipsis(x - font_size, y, color, font_size);
                }
                return;
            }
        }

        // 检查是否超出屏幕底部
        if (y + metrics.height > fb_->height) {
            render_ellipsis(x, y, color, font_size);
            return;
        }

        // 渲染字符
        font_renderer_->render_char(fb_, char_code, x, y, color, font_size, is_chinese);
        y += metrics.height;
        i += char_len;
    }
}

void TextRenderer::render_ellipsis(int x, int y, uint16_t color, int font_size) {
    if (!fb_ || !font_renderer_) return;

    // 省略号Unicode编码
    constexpr uint32_t ELLIPSIS_CHAR = 0x2026;
    font_renderer_->render_char(fb_, ELLIPSIS_CHAR, x, y, color, font_size, false);
}

size_t TextRenderer::decode_utf8(const std::string &str, size_t pos, uint32_t &out) {
    if (pos >= str.size()) {
        out = 0;
        return 0;
    }

    const unsigned char lead = static_cast<unsigned char>(str[pos]);

    if ((lead & 0x80) == 0) {
        out = lead;
        return 1;
    } else if ((lead & 0xE0) == 0xC0) {
        if (pos + 1 >= str.size()) return 1;
        out = ((lead & 0x1F) << 6) | (str[pos + 1] & 0x3F);
        return 2;
    } else if ((lead & 0xF0) == 0xE0) {
        if (pos + 2 >= str.size()) return 1;
        out = ((lead & 0x0F) << 12) |
              ((static_cast<unsigned char>(str[pos + 1]) & 0x3F) << 6) |
              (static_cast<unsigned char>(str[pos + 2]) & 0x3F);
        return 3;
    } else {
        out = lead;
        return 1;
    }
}
